from flask import request, make_response
import threading
import redis
import time

from utils import utils
from user import user_thread


class UserCharge:
    @staticmethod
    def send_appointment():
        db = redis.Redis(host="localhost", port=6379, decode_responses=True)
        res = {
            "ok": True
        }

        data = request.get_json()
        user_id = data["id"]
        mode = data["mode"]
        amount = data["amount"]

        # print(data)
        if utils.full_wait_queue():
            res["ok"] = False
        else:
            time_stamp = utils.push_wait_queue(mode, user_id)
            order_id = utils.set_order(user_id, mode, amount, time_stamp)

            user_tuple = user_id, order_id
            thread = threading.Thread(target=user_thread.user_thread, args=user_tuple)
            thread.start()
        return make_response(res)

    @staticmethod
    def change_appointment():
        db = redis.Redis(host="localhost", port=6379, decode_responses=True)
        res = {
            "ok": True
        }

        data = request.get_json()
        user_id = data["id"]
        amount = data["amount"]
        mode = data["mode"]

        where = db.hget(user_id, "where")
        order_id = db.hget(user_id, "order")
        user_mode = db.hget(user_id, "mode")
        user_amount = db.hget(user_id, "amount")
        if where == "charge":
            res["ok"] = False
        elif where == "wait":
            if mode == "F" or mode == "T":
                if user_mode != mode:
                    utils.pop_wait_queue(user_mode, user_id)
                    utils.push_wait_queue(mode, user_id)
            if amount > 0:
                if user_amount != amount:
                    db.hset(user_id, "amount", amount)
            new_mode = db.hget(user_id, "mode")
            new_amount = float(db.hget(user_id, "amount"))
            power_rate = utils.get_power_rate(new_mode)
            charge_time = new_amount / power_rate * 3600
            db.hset(order_id, "charge_time", str(charge_time))
        return make_response(res)

    @staticmethod
    def cancel_appointment():
        db = redis.Redis(host="localhost", port=6379, decode_responses=True)
        res = {
            "ok": True
        }

        data = request.get_json()
        user_id = data["id"]

        where = db.hget(user_id, "where")
        db.hset(user_id, "where", "exit")
        if where == "wait":
            mode = db.hget(user_id, "mode")
            utils.pop_wait_queue(mode, user_id)
        elif where == "charge":
            utils.end_order(user_id)
        return make_response(res)

    @staticmethod
    def get_where():
        db = redis.Redis(host="localhost", port=6379, decode_responses=True)
        res = {
            "where": ""
        }

        data = request.get_json()
        user_id = data["id"]

        res["where"] = db.hget(user_id, "where")
        return make_response(res)

    @staticmethod
    def get_state():
        db = redis.Redis(host="localhost", port=6379, decode_responses=True)
        res = {
            "state": ""
        }

        data = request.get_json()
        user_id = data["id"]

        res["state"] = db.hget(user_id, "state")
        return make_response(res)

    @staticmethod
    def get_front_number():
        db = redis.Redis(host="localhost", port=6379, decode_responses=True)
        res = {
            "ok": True,
            "num": 0
        }

        data = request.get_json()
        user_id = data["id"]

        where = db.hget(user_id, "where")
        if where == "wait":
            mode = db.hget(user_id, "mode")
            res["num"] = db.zrank(mode + "_QUEUE", user_id)
        elif where == "charge":
            order_id = db.hget(user_id, "order")
            station_id = db.hget(order_id, "station_id")
            res["num"] = db.zrank(station_id + "_QUEUE", user_id)
        else:
            res["ok"] = False

        return make_response(res)

    @staticmethod
    def get_wait_label():
        db = redis.Redis(host="localhost", port=6379, decode_responses=True)
        res = {
            "ok": True,
            "label": ""
        }

        data = request.get_json()
        user_id = data["id"]

        where = db.hget(user_id, "where")
        if where == "wait":
            mode = db.hget(user_id, "mode")
            rank = int(db.zrank(mode + "_QUEUE", user_id))
            res["label"] = mode + str(rank+1)
        else:
            res["ok"] = False
        return make_response(res)